class WxRequest{
  defaults = {
    baseUrl: 'https://gmall-prod.atguigu.cn/mall-api11',// 请求基准地址
    url: '',// 开发者服务器接口地址
    data: null,// 请求参数
    method: 'GET',// 默认请求方法
    header:{
      'Content-type': 'application/json' // 设置数据的交互格式
    },
    timeout: 60000 // 小程序默认超时时间是 60000，一分钟 请求时间
  }

  /**
   * @description 定义 constructor 构造函数，用于创建和初始化类的属性和方法
   * @param {*} params 用户传入的请求配置项
   */
  constructor(params = {}){
    // 在实例化时传入的参数能够被 constructor 进行接收
    // 使用 Object.assign 合并默认参数以及传递的请求参数
    this.defaults = Object.assign({}, this.defaults, params)
  }

  //定义拦截器
  interceptors = {
    //请求拦截
    request:(config) => config,
    response:(response) => response
  }

  request(optiongs){
    // 拼接完整的请求地址
    optiongs.url = this.defaults.baseUrl + optiongs.url
    //合并请求参数
    optiongs = {...this.defaults,...optiongs}
    // wx.showLoading()
    //在发送之前调用请求拦截器
    this.interceptors.request(optiongs)
    //需要使用Promise封装wx.request，处理异步请求
    return new Promise((resolve,reject) =>{
           if (optiongs.method === 'UPLOAD') {
              wx.uploadFile({
                 ...optiongs,
         
                 success: (res) => {
                   // 将服务器响应的数据通过 JSON.parse 转换为 JS 对象
                   res.data = JSON.parse(res.data)
                   console.log(res)
                   const mergeRes = Object.assign({}, res, {
                     config: optiongs,
                     isSuccess: true
                   })
                   console.log(mergeRes)
                   resolve(this.interceptors.response(mergeRes))
                 },
         
                 fail: (err) => {
                   const mergeErr = Object.assign({}, err, {
                    config: optiongs,
                     isSuccess: true
                   })
         
                   reject(this.interceptors.response(mergeErr))
                 },
               })
        }else{
      wx.request({
         ...optiongs,
         success:(res)=>{
          //不管接口成功还是失败，都需要调用响应拦截器
          // 第一个参数：需要合并的目标对象
          // 第二个参数：服务器响应的数据
          // 第三个参数：请求配置以及自定义的属性
          const mergetRes = Object.assign({}, res, { config: optiongs ,isSuccess:true})
           resolve(this.interceptors.response(mergetRes))
         },

        fail:(err)=>{
          if(this.interceptors.response){
            err = this.interceptors.response({response:err,isSuccess:false})
          }
          reject(err)
        },
        complete: () => {
                     // 接口调用完成后隐藏 loding
                    //  wx.hideLoading()
                   }
      })
    }
    })
  
  }
  //get方法
  get(url,data={},config={}){
    return this.request(Object.assign({url,data,method:'GET'},config))
  }
  post(url,data={},config={}){
    return this.request(Object.assign({url,data,method:'POST'},config))
  }
  put(url,data={},config={}){
    return this.request(Object.assign({url,data,method:'PUT'},config))
  }
  delete(url,data={},config={}){
    return this.request(Object.assign({url,data,method:'DELETE'},config))
  }

  all(...promise) {
         return Promise.all(promise)
  }

    /**
   * @description upload 实例方法，用来对 wx.uploadFile 进行封装
   * @param {*} url 文件的上传地址、接口地址
   * @param {*} filePath 要上传的文件资源路径
   * @param {*} name 文件对应的 key
   * @param {*} config 其他配置项
   */
  upload(url, filePath, name = 'file', config = {}) {
    return this.request(
      Object.assign({ url, filePath, name, method: 'UPLOAD' }, config)
    )
  }
}

export default WxRequest
